﻿using System;
using Cms.Application.Admin.Presenters;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Cms.Domain;
using Cms.Application.Admin.Views;
using Moq;
using Cms.Utilities;

namespace Cms.Tests.Unit.Application.Admin.Presenters
{
    [TestClass]
    public class AdminMasterPresenterTests : BasePresenterTests
    {
        private Administrator _admin;
        private Mock<IAdminMasterView> _viewMock;
        private Site _currentSite;
        private Mock<IUpdater> _updaterMock;
        private Cms.Utilities.Version _version;
        private AdminMasterPresenter _presenter;

        private void GeneralPrepare()
        {
            _admin = new Administrator
            {
                DefaultSystemLocale = "en-US",
                Email = "test@fredium.com",
                Firstname = "Charles",
                Lastname = "Bronson",
                Password = "dontmess",
                Username = "daman",
                DateFormat = "yyyy-MM-dd",
                TimeFormat = "HH:mm",
                Created = new DateTime(2010, 03, 19),
            };
            AdministratorGroup group = new AdministratorGroup { ID = 1 };
            group.Administrators.Add(_admin);
            _admin.Group = group;
            _currentSite = new Site() { Domain = "www.xx.com" };
            _admin.CurrentSite = _currentSite;
            InitRepositoryFactoryMock();
            AdministratorRepositoryMock.Setup(a => a.GetAdministrator(1)).Returns(_admin);
            _viewMock = new Mock<IAdminMasterView>();
            _viewMock.SetupAllProperties();
            _viewMock.Setup(v => v.AdministratorID).Returns(1);
            _updaterMock = new Mock<IUpdater>();
            _version = new Cms.Utilities.Version("1.2.3.4");
            _updaterMock.Setup(m => m.GetCurrentVersion()).Returns(_version);
        }

        [TestMethod]
        public void Constructor_SiteAndAdminExists_Success()
        {
            GeneralPrepare();
            AdminMasterPresenter presenter = new AdminMasterPresenter(_viewMock.Object, FactoryMock.Object);
            _viewMock.Verify(m => m.SetAdministratorName(_admin.Fullname));
            _viewMock.Verify(m => m.SetSystemCulture(_admin));
        }

        private void PrepareInitialize()
        {
            // GeneralPrepare must be called before this method!
            _presenter = new AdminMasterPresenter(_viewMock.Object, FactoryMock.Object)
                              {Updater = _updaterMock.Object};
            _presenter.Initialize();
        }
        
        [TestMethod]
        public void Initialize_SetCurrentSiteAndVersion_Success()
        {
            GeneralPrepare();
            PrepareInitialize();
            _viewMock.Verify(m => m.SetCurrentSite(_currentSite.Domain));
            _viewMock.Verify(m => m.SetSystemVersion(_version.Full));
        }
        
        [TestMethod]
        public void Initialize_AdminWantsIntroHelp_NotYetDisplayed_ShowHelp()
        {
            GeneralPrepare();
            _admin.ShowIntroHelp = true;
            _viewMock.Setup(m => m.IntroHelpDisplayed).Returns(false);
            PrepareInitialize();
            _viewMock.Verify(m => m.ShowIntroHelp(), Times.Once());
        }
        
        [TestMethod]
        public void Initialize_AdminWantsIntroHelp_AlreadyDisplayed_DontShowHelp()
        {
            GeneralPrepare();
            _admin.ShowIntroHelp = true;
            _viewMock.Setup(m => m.IntroHelpDisplayed).Returns(true);
            PrepareInitialize();
            _viewMock.Verify(m => m.ShowIntroHelp(), Times.Never());
        }
        
        [TestMethod]
        public void Initialize_AdminDontWantIntroHelp_DontShowHelp()
        {
            GeneralPrepare();
            _admin.ShowIntroHelp = false;
            _viewMock.Setup(m => m.IntroHelpDisplayed).Returns(false);
            PrepareInitialize();
            _viewMock.Verify(m => m.ShowIntroHelp(), Times.Never());
        }
        
        [TestMethod]
        public void GetAvailableSites_Success()
        {
            GeneralPrepare();
            AdminMasterPresenter presenter = new AdminMasterPresenter(_viewMock.Object, FactoryMock.Object);
            presenter.GetAvailableSites();
            _viewMock.Verify(m => m.SetAvailableSites(_admin.AvailableSites),Times.Once());
        }
    }
}
